﻿using System;
using System.Collections.Generic;
using System.Text;
using ChemicalEquilibrium;

namespace NeuralModule
{
    /// <summary>
    /// 后突触
    /// 分类
    ///     简单后突触
    ///         功能:
    ///             将递质转化为离子通道的开放
    ///         组成:
    ///             钾离子
    ///             钠离子
    ///             钾离子通道
    ///             钠离子通道
    ///             递质门控钠离子通道
    ///         平衡:
    ///             离子平衡
    ///             通道受体激活失活平衡
    ///         过程
    ///             由前突触释放的递质与递质门控钠离子通道受体结合
    ///             递质门控钠通道开放
    ///             
    ///             
    /// </summary>
    public class Postsynaptic
    {
        public List<ThreadEventWait> TEWs = new List<ThreadEventWait>();

        public Reactants FormerTransmitter;

        public Reactants IonK, IonNa;
        public Reactants ChannelK, ChannelNa, PumpNaK;
        public Reactants ReceptorChannelNa, ReceptorTransmitterChannelNa;

        //递质分解酶
        public Reactants EnzymeResolve;

        public IonicEquilibrium IEK, IENa, IETransmitterNa;

        public IonicPump IPNaK;


        public ReactCombine RCTransmitterChannelNa;

        public ReactActivate RATransmitterResolve;

        //递质门控Na通道受体电导
        float conductanceReceptor = 0.1f;

        public Postsynaptic(Reactants formerTransmitter)
        {
            this.FormerTransmitter = formerTransmitter;

            Initialize();
        }

        public void Initialize()
        {
            //离子
            this.IonK = new Reactants(100000, 100000);
            this.IonNa = new Reactants(100000, 100000);

            //离子通道
            this.ChannelK = new Reactants(1000, 0);
            this.ChannelNa = new Reactants(1000, 0);

            //离子泵
            this.PumpNaK = new Reactants(20, 0);

            //递质分解酶
            this.EnzymeResolve = new Reactants(100, 0);


            //递质门控受体Na离子通道
            this.ReceptorChannelNa = new Reactants(1000,0);
            this.ReceptorTransmitterChannelNa = new Reactants(0, 1000);

            //离子平衡系统
            this.IEK = new IonicEquilibrium(this.ChannelK.Active, this.IonK.Active, this.IonK.Inactive, 0.009f, -80, this.GetVoltage);
            this.IENa = new IonicEquilibrium(this.ChannelNa.Active, this.IonNa.Active, this.IonNa.Inactive, 0.001f, 62, this.GetVoltage);

            //离子泵平衡系统
            this.IPNaK = new IonicPump(this.PumpNaK.Active, new Queue<Reactant>[] { this.IonK.Active, this.IonNa.Active }, new Queue<Reactant>[] { this.IonK.Inactive, this.IonNa.Inactive }, new int[] { 200, -200 }, new int[] { 90000, 110000 });

            //递质门控受体离子通道离子平衡系统
            this.IETransmitterNa = new IonicEquilibrium(this.ReceptorTransmitterChannelNa.Active, this.IonNa.Active, this.IonNa.Inactive, conductanceReceptor, 62, this.GetVoltage);

            //递质与受体化合平衡系统
            this.RCTransmitterChannelNa = new ReactCombine(this.FormerTransmitter.Active, this.ReceptorChannelNa.Active, this.ReceptorTransmitterChannelNa.Active, this.ReceptorTransmitterChannelNa.Inactive, null, 10, 10, 1, 1);

            //递质分解系统
            this.RATransmitterResolve = new ReactActivate(this.FormerTransmitter.Active, this.FormerTransmitter.Inactive, this.EnzymeResolve.Active, new Queue<Reactant>(), 10, 5, 1, 1);

            //线程
            this.TEWs.Add(new ThreadEventWait(10, new OperateCallback(this.IEK.Transport)));
            this.TEWs.Add(new ThreadEventWait(10, new OperateCallback(this.IENa.Transport)));
            this.TEWs.Add(new ThreadEventWait(10, new OperateCallback(this.IPNaK.Transport)));

            this.TEWs.Add(new ThreadEventWait(10, new OperateCallback(this.IETransmitterNa.Transport)));
            this.TEWs.Add(new ThreadEventWait(10, new OperateCallback(this.RCTransmitterChannelNa.Combine)));
            this.TEWs.Add(new ThreadEventWait(10, new OperateCallback(this.RCTransmitterChannelNa.Resolve)));
            this.TEWs.Add(new ThreadEventWait(10, new OperateCallback(this.RATransmitterResolve.Inactivate)));
        }


        public void Start()
        {
            foreach (ThreadEventWait TEW in this.TEWs) TEW.Start();
        }

        public void Abort()
        {
            foreach (ThreadEventWait TEW in this.TEWs) TEW.Abort();
        }

        float Capacitance = 0.0005f;
        public int GetVoltage()
        {
            int voltage = (int)((this.IonK.Active.Count + this.IonNa.Active.Count - this.IonK.Inactive.Count - this.IonK.Inactive.Count) * this.Capacitance);
            return voltage;
        }
    }
}
